﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenExpressApp.WPF.Templete;
using System.Windows.Markup;
using System.Xml;
using System.IO;
using System.Windows;
using OpenExpressApp.WPF;
using OpenExpressApp.Template;
using OpenExpressApp.Types;
using System.Diagnostics;
using OpenExpressApp.MetaModel;
using AvalonDock;
using System.Windows.Controls;
using OpenExpressApp.WPF.SystemModule;
using OpenExpressApp.MetaModel.Audit;
using OpenExpressApp.Module.Library.Security;
using System.Collections.ObjectModel;
using Csla;
using System.ComponentModel.Composition;
using System.Windows.Controls.Primitives;
using System.ComponentModel.Composition.Hosting;
using OpenExpressApp.Library;

namespace OpenExpressApp.Module.WPF
{
    public class OpenApplication
    {
        public static readonly Dictionary<Type, ListForm> ListPad = new Dictionary<Type, ListForm>();

        public static CompositionContainer CompositionContainer;

        /// <summary>
        /// 构造模块的窗口
        /// </summary>
        /// <param name="boType"></param>
        public static IWindowTemplate CreateModuleForm(BusinessObjectInfo boInfo)
        {
            Debug.Assert(boInfo.IsDefaultObject, "只有默认对象才允许调用CreateModuleForm");
            //根据类型通过模板生成UI
            IWindowTemplate window = null;
            switch (boInfo.DefaultObjectAttribute.ModuleType)
            {
                case ModuleType.List:
                    window = new ListForm(boInfo.BOType);
                    break;
                case ModuleType.Query:
                    window = new QueryForm(boInfo.BOType);
                    break;
                default:
                    window = new ListDetailForm(boInfo.BOType);
                    break;
            }
            return window;
        }

        /// <summary>
        /// 根据类型通过模板生成UI
        /// </summary>
        /// <param name="boType"></param>
        /// <param name="getListParam"></param>
        /// <returns></returns>
        public static IWindowTemplate CreateListForm(Type boType, params object[] getListParam)
        {
            return new ListForm(boType, getListParam);
        }

        /// <summary>
        /// 根据类型通过模板生成UI
        /// </summary>
        /// <param name="boType"></param>
        /// <param name="getListParam"></param>
        /// <returns></returns>
        public static IWindowTemplate CreatePopupForm(Type boType, params object[] getListParam)
        {
            return new PopupForm(boType, getListParam);
        }

        public static IWindowTemplate CreatePopupForm(Type boType, string getListMethod, params object[] getListParam)
        {
            return new PopupForm(boType, getListMethod, getListParam);
        }

        /// <summary>
        /// 根据类型通过模板生成UI，设置初始数据为data
        /// </summary>
        /// <typeparam name="TBOType"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static IWindowTemplate CreatePopupForm<TBOType>(object data)
        {
            var form = new PopupForm(typeof(TBOType));
            form.View.Data = data;
            return form;
        }

        /// <summary>
        /// 根据类型通过模板生成UI
        /// </summary>
        /// <param name="boType"></param>
        /// <param name="getListParam"></param>
        /// <returns></returns>
        public static object CreateApplicationListPad(Type boType, params object[] getListParam)
        {
            if (ListPad.ContainsKey(boType) == false)
            {
                ListForm pad = new ListForm(boType, getListParam);
                Pads.Items.Add(pad);
                ListPad.Add(boType, pad);
                return pad;
            }
            return ListPad[boType];
        }

        public static IWindowTemplate CreateViewListPad(ObjectView view, Type boType, params object[] getListParam)
        {
            DockablePane pane = view.GetRootView().GetFrameTemplate().GetRegion(ViewRegionNames.Pads) as DockablePane;
            //根据类型通过模板生成UI
            if (!view.PadDict.ContainsKey(boType))
            {
                ListForm pad = new ListForm(boType, getListParam);
                DockableContent dc = new DockableContent() { Content = pad, Title = ApplicationModel.GetBusinessObjectInfo(boType).Label };
                dc.HideOnClose = true;
                pane.Items.Add(dc);
                view.PadDict.Add(boType, pad);
                pane.GetManager().Show(dc);
                pane.PreviewMouseDown += (sender, e) =>
                {
                    if (e.OriginalSource is DockablePane)
                        e.Handled = true;
                };
                return pad;
            }
            ListForm l = view.PadDict[boType] as ListForm;
            pane.GetManager().Show(l.GetVisualChild<DockableContent>());
            return l;
        }

        public static bool? ShowDialog(object form, DialogOptions options, Func<bool> validationAction, string[] commandNames)
        {
            IFrameTemplate frameTemplate = (form as FrameworkElement).GetFrameTemplate();
            frameTemplate.View.RegionType = RegionType.Dialog;

            return DialogWorkspace.ShowView(form, options, validationAction, commandNames);
        }

        /// <summary>
        /// 打开指定类型的模块
        /// </summary>
        /// <param name="boType"></param>
        public static object OpenModule(Type boType)
        {
            BusinessObjectInfo selectItem = GetModule(boType);
            Debug.Assert(selectItem != null, "未找到这个模块，不能打开！");

            //检查是不是有权限打开此模块
            var currentIdentity = ApplicationContext.User.Identity as OEAIdentity;
            var operationId = new Guid(CommandNames.CanViewObject);
            if (!currentIdentity.HavePermissionOnOperation(selectItem.Id, operationId))
            {
                MessageBox.Show("你没有权限打开此模块");
                return null;
            }

            //左边的控件
            ModuleListBox.SelectedItem = selectItem;

            //右边的控件
            object view = CreateView(selectItem);

            //日志
            AuditLogService.LogAsync(new AuditLogItem()
            {
                Title = "打开模块：" + selectItem.Label,
                ModuleName = selectItem.Label,
                Type = AuditLogType.OpenModule
            });

            return view;
        }

        /// <summary>
        /// 创建/找到具体的视图控件。
        /// </summary>
        /// <param name="mainRegion"></param>
        /// <param name="selectItem"></param>
        /// <param name="view"></param>
        /// <returns></returns>
        private static object CreateView(BusinessObjectInfo selectItem)
        {
            object view = Workspace.GetWindow(selectItem.Label);

            //如果已经打开则激活模块，否则新增模块窗体
            if (view == null)
            {
                if (selectItem.ModuleUIType != null)
                {
                    view = Activator.CreateInstance(selectItem.ModuleUIType);
                }
                else
                {
                    view = CreateModuleForm(selectItem);
                }

                Workspace.Add(view as IWindow);
            }

            Workspace.Active(view as IWindow);

            return view;
        }

        /// <summary>
        /// 获取指定类型的模块
        /// </summary>
        /// <param name="boType"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        private static BusinessObjectInfo GetModule(Type boType)
        {
            foreach (var item in ModuleListBox.Items)
            {
                if ((item as BusinessObjectInfo).BOType == boType)
                {
                    return item as BusinessObjectInfo;
                }
            }
            return null;
        }

        #region 界面区域

        public static IWorkspace Workspace
        {
            get
            {
                return CompositionContainer.GetExportedValue<IWorkspace>(ContractName.Workspace);
            }
        }

        public static Control ModuleListPad
        {
            get
            {
                return CompositionContainer.GetExportedValue<Control>(ContractName.ModuleListPad);
            }
        }


        public static ItemsControl Pads
        {
            get
            {
                return CompositionContainer.GetExportedValue<ItemsControl>(ContractName.Pads);
            }
        }

        public static Selector ModuleListBox
        {
            get
            {
                return CompositionContainer.GetExportedValue<Selector>(ContractName.ModuleListBox);
            }
        }

        #endregion
    }
}
